<template>
  <div class="cgl-container">
    <!-- 头部标题 -->
    <div class="header">
      <div class="titleMain">连退2150炉辊张力辊打滑预警模型</div>
    </div>

    <!-- Top Charts Area -->
    <div class="top-charts-panel">
      <div class="chart-card status-chart">
        <div class="chart-header">
          <div class="title-bar">
            <span class="blue-bar"></span>
            <span class="title-text">工艺辊服役状态</span>
          </div>
          <div class="chart-buttons">
            <el-radio-group v-model="barChartType" size="small" @change="updateBarChart">
              <el-radio-button label="超差辊"></el-radio-button>
              <el-radio-button label="公里数"></el-radio-button>
              <el-radio-button label="粗糙度"></el-radio-button>
            </el-radio-group>
          </div>
        </div>
        <div class="chart-content" ref="statusBarChartRef"></div>
      </div>
      <div class="chart-card line-chart">
        <div class="chart-header">
          <div class="title-bar">
            <span class="blue-bar"></span>
            <span class="title-text">出口段</span>
          </div>
          <div class="chart-controls">
            <el-select v-model="torqueSelect1" placeholder="选择关键辊" size="small" class="torque-select" @change="handleTorqueSelect1Change">
              <el-option v-for="option in torqueOptions1" :key="option.value" :label="option.label" :value="option.value"> </el-option>
            </el-select>
          </div>
        </div>
        <div class="chart-content" ref="lineChart1Ref"></div>
      </div>
      <div class="chart-card line-chart">
        <div class="chart-header">
          <div class="title-bar">
            <span class="blue-bar"></span>
            <span class="title-text">工艺段</span>
          </div>
          <div class="chart-controls">
            <el-select v-model="torqueSelect2" placeholder="选择关键辊" size="small" class="torque-select" @change="handleTorqueSelect2Change">
              <el-option v-for="option in torqueOptions2" :key="option.value" :label="option.label" :value="option.value"> </el-option>
            </el-select>
          </div>
        </div>
        <div class="chart-content" ref="lineChart2Ref"></div>
      </div>
      <div class="chart-card line-chart">
        <div class="chart-header">
          <div class="title-bar">
            <span class="blue-bar"></span>
            <span class="title-text">入口段</span>
          </div>
          <div class="chart-controls">
            <el-select v-model="torqueSelect3" placeholder="选择关键辊" size="small" class="torque-select" @change="handleTorqueSelect3Change">
              <el-option v-for="option in torqueOptions3" :key="option.value" :label="option.label" :value="option.value"> </el-option>
            </el-select>
          </div>
        </div>
        <div class="chart-content" ref="lineChart3Ref"></div>
      </div>
    </div>

    <!-- Process Flow and Stats Area -->
    <el-row class="process-stats-panel">
      <!-- 辊位图 点击热区  -->
      <div class="roll-pos-image-block" @click="rollPosImageRef?.openDialog('3')"></div>
      <div class="roll-pos-image-block" @click="rollPosImageRef?.openDialog('2')"></div>
      <div class="roll-pos-image-block" @click="rollPosImageRef?.openDialog('1')"></div>
      <!-- 报警信息 - 左上角 -->
      <div class="warning-banner warning-banner-top-left">
        <i class="fa fa-exclamation-triangle"></i>
        报警信息 {{ warningMessage }}
      </div>

      <div class="svg">
        <svg-load :name="technologicalName" style="z-index: 999"></svg-load>
      </div>

      <!-- 张力信息 - 右上角 -->
      <div class="tension-info tension-info-top-right">
        设定张力:
        <strong>{{ tensionInfo.set }}KN</strong> 实际张力:
        <strong>{{ tensionInfo.actual }}KN</strong>
      </div>

      <!-- Added Data Layer for Gauges and Live Data -->
      <div class="zlgdh-added-data-layer">
        <!-- Gauges -->
        <div class="gauge-wrapper zlgdh-gauge-ent">
          <div class="gauge-title">出口速度</div>
          <div id="zlgdh_speed_exit" class="gauge-container"></div>
        </div>
        <div class="gauge-wrapper zlgdh-gauge-process">
          <div class="gauge-title">工艺速度</div>
          <div id="zlgdh_speed_process" class="gauge-container"></div>
        </div>
        <div class="gauge-wrapper zlgdh-gauge-exit">
          <div class="gauge-title">入口速度</div>
          <div id="zlgdh_speed_ent" class="gauge-container"></div>
        </div>

        <!-- Live Data Boxes -->
        <div class="semitransp_box zlgdh_inlet_looper">
          <p>出口活套:</p>
          <p>{{ numberFormat(zlgdhExportLooper * 100, 0) }} %</p>
        </div>
        <div class="semitransp_box zlgdh_middle_looper">
          <p>中间活套:</p>
          <p>{{ numberFormat(zlgdhMiddleLooper * 100, 0) }} %</p>
        </div>
        <div class="semitransp_box zlgdh_export_looper">
          <p>入口活套:</p>
          <p>{{ numberFormat(zlgdhInletLooper * 100, 0) }} %</p>
        </div>
        <div class="semitransp_box zlgdh_cpc_width" :class="{ is_alarm: zlgdhCpcWidthAlarm }">
          <p>CPC测宽:</p>
          <p>{{ numberFormat(zlgdhCpcWidth, 1) }}mm</p>
        </div>
        <div class="semitransp_box zlgdh_inlet_looper_time">
          <p>出口套时间:</p>
          <p>{{ zlgdhExportLooperTime }}</p>
        </div>
        <div class="semitransp_box zlgdh_middle_looper_time">
          <p>中间套时间:</p>
          <p>{{ zlgdhMiddleLooperTime }}</p>
        </div>
        <div class="semitransp_box zlgdh_export_looper_time">
          <p>入口套时间:</p>
          <p>{{ zlgdhInletLooperTime }}</p>
        </div>
        <div class="semitransp_box zlgdh_uncoiler_len_a">
          <p>#1卷取长度:</p>
          <p>{{ numberFormat(zlgdhCoilerLenA, 0) }} m</p>
        </div>
        <div class="semitransp_box zlgdh_uncoiler_len_b">
          <p>#2卷取长度:</p>
          <p>{{ numberFormat(zlgdhCoilerLenB, 0) }} m</p>
        </div>
        <div class="semitransp_box zlgdh_coiler_len_a">
          <p>#1开卷长度:</p>
          <p>{{ numberFormat(zlgdhUncoilerLenA, 0) }} m</p>
        </div>
        <div class="semitransp_box zlgdh_coiler_len_b">
          <p>#2开卷长度:</p>
          <p>{{ numberFormat(zlgdhUncoilerLenB, 0) }} m</p>
        </div>
      </div>

      <!-- 酸轧厚度板形判别调优模型图 (替代SVG) -->
      <div class="process-diagram">
        <!-- 流程线条 -->
        <div class="process-flow-lines">
          <div class="flow-line horizontal-main"></div>
          <div class="flow-line vertical-line1"></div>
          <div class="flow-line vertical-line2"></div>
          <div class="flow-line vertical-line3"></div>
          <div class="flow-line vertical-line4"></div>
          <div class="flow-dot dot1"></div>
          <div class="flow-dot dot2"></div>
          <div class="flow-dot dot3"></div>
          <div class="flow-dot dot4"></div>
          <div class="flow-dot dot5"></div>
        </div>

        <!-- 数据流动效果 -->
        <div class="data-flow">
          <div class="data-particle particle1"></div>
          <div class="data-particle particle2"></div>
          <div class="data-particle particle3"></div>
          <div class="data-particle particle4"></div>
        </div>

        <!-- 科技感装饰元素 -->
        <div class="tech-decorations">
          <div class="tech-circle circle1"></div>
          <div class="tech-circle circle2"></div>
          <div class="tech-hexagon hex1"></div>
          <div class="tech-hexagon hex2"></div>
          <div class="tech-scan-line"></div>
        </div>
      </div>
    </el-row>

    <!-- Warning Banner -->

    <!-- Bottom Table Area -->
    <div class="bottom-panel">
      <div class="tables-wrapper">
        <!-- Left Table Card -->
        <div class="table-card left-table-card">
          <div class="card-header">
            <div class="title-icon-left"></div>
            <span>报警时间与原因</span>
            <div class="title-icon-right"></div>
          </div>
          <el-table
            :data="tableData"
            class="left-table"
            style="width: 100%; height: 100%"
            border
            size="small"
            :header-cell-style="rightTableHeaderStyle"
            :cell-style="rightTableCellStyle"
          >
            <el-table-column prop="modifyTime" label="时间" />
            <el-table-column prop="rollID" label="打滑辊号" />
            <el-table-column prop="slipReason" label="打滑原因">
              <template #default="scope">
                <span>{{ scope.row.slipReason == 1 ? '周期打滑' : scope.row.slipReason == 2 ? '升降速打滑' : '瞬时打滑' }}</span>
              </template>
            </el-table-column>
            <el-table-column label="操作">
              <template #default="scope">
                <el-button v-if="!scope.row.confirmed" type="primary" size="small" @click="confirmRow(scope.$index)">确认</el-button>
                <span v-else style="color: #67c23a">已完成</span>
              </template>
            </el-table-column>
          </el-table>
        </div>
      </div>
    </div>
  </div>
  <RollPosImage r-group="5709/2150连退机组" :tab-list="rollPosImageList" ref="rollPosImageRef" />
</template>

<script setup lang="ts">
  import { ref, reactive, computed, onMounted, onUnmounted, nextTick } from 'vue';
  import * as echarts from 'echarts/core';
  import { BarChart, LineChart, GaugeChart } from 'echarts/charts';
  import { TitleComponent, TooltipComponent, GridComponent, LegendComponent, MarkLineComponent } from 'echarts/components';
  import { CanvasRenderer } from 'echarts/renderers';
  import axios from 'axios';
  import { rollingSimulationApi } from '/@/api/RollingSimulation/index';
  import { refreshSVG, initialSVG, refreshGraphical } from '/@/common/refreshSVG';
  import RollPosImage from '/@/views/common/RollPosImage/RollPosImage.vue';
  import { useUserStore } from '/@/store/modules/system/user';
  // Register ECharts components
  echarts.use([TitleComponent, TooltipComponent, GridComponent, LegendComponent, BarChart, LineChart, GaugeChart, CanvasRenderer, MarkLineComponent]);

  const menuData = ref([
    { menuName: 'ZLGDH-CAL2150', menuTitle: '连退2150炉辊张力辊打滑模型主页', menuId: '1' },
    { menuName: '2150SlipHistory', menuTitle: '历史记录' },
    { menuName: '2150SlipReport', menuTitle: '打滑报表' },
    { menuName: '2150TensionSelfLearning', menuTitle: '张力设定表' },
    { menuName: '2150ModelRuleSetting', menuTitle: '模型规则设定' },
  ]);
  onBeforeMount(() => {
    useUserStore().setTagNav(menuData.value);
  });

  const rollPosImageList = [
    {
      label: 'CAL2150入口',
      key: '1',
      svgUrl: '/rollPosImage/2150/CAL2150入口.svg',
    },
    {
      label: 'CAL2150炉子',
      key: '2',
      svgUrl: '/rollPosImage/2150/CAL2150炉子.svg',
    },
    {
      label: 'CAL2150出口',
      key: '3',
      svgUrl: '/rollPosImage/2150/CAL2150出口.svg',
    },
  ];

  const rollPosImageRef = ref<InstanceType<typeof RollPosImage> | null>(null);

  // --- Refs for Charts ---
  const statusBarChartRef = ref<HTMLElement | null>(null);
  const lineChart1Ref = ref<HTMLElement | null>(null);
  const lineChart2Ref = ref<HTMLElement | null>(null);
  const lineChart3Ref = ref<HTMLElement | null>(null);

  // --- ECharts Instances ---
  let statusBarChartInstance: echarts.ECharts | null = null;
  let lineChart1Instance: echarts.ECharts | null = null;
  let lineChart2Instance: echarts.ECharts | null = null;
  let lineChart3Instance: echarts.ECharts | null = null;

  // --- 柱状图类型选择 ---
  const barChartType = ref('超差辊');

  // --- State ---
  const torqueSelect1 = ref('');
  const torqueSelect2 = ref('');
  const torqueSelect3 = ref('');

  // --- 下拉框选项 ---
  const torqueOptions1 = ref<Array<{ label: string; value: string }>>([]); // 出口段
  const torqueOptions2 = ref<Array<{ label: string; value: string }>>([]); // 工艺段
  const torqueOptions3 = ref<Array<{ label: string; value: string }>>([]); // 入口段

  // --- 实时数据轮询相关变量 ---
  const realDataTimer1 = ref<NodeJS.Timeout | null>(null);
  const realDataTimer2 = ref<NodeJS.Timeout | null>(null);
  const realDataTimer3 = ref<NodeJS.Timeout | null>(null);

  // --- 实时数据存储 ---
  const realData1 = ref<Array<{ time: string; values: number[] }>>([]);
  const realData2 = ref<Array<{ time: string; values: number[] }>>([]);
  const realData3 = ref<Array<{ time: string; values: number[] }>>([]);

  // --- 当前选中的dicPropCode值 ---
  const currentDicPropCodes1 = ref<string[]>([]);
  const currentDicPropCodes2 = ref<string[]>([]);
  const currentDicPropCodes3 = ref<string[]>([]);

  // --- 当前选中的dicPropName值 ---
  const currentDicPropNames1 = ref<string[]>([]);
  const currentDicPropNames2 = ref<string[]>([]);
  const currentDicPropNames3 = ref<string[]>([]);

  // 处理关键辊选择变化的函数
  const handleTorqueSelect1Change = async (value: string) => {
    // 停止之前的轮询
    stopRealDataPolling(1);

    if (value) {
      await callGetDicPropCode(value, 1);
    }
  };

  const handleTorqueSelect2Change = async (value: string) => {
    // 停止之前的轮询
    stopRealDataPolling(2);

    if (value) {
      await callGetDicPropCode(value, 2);
    }
  };

  const handleTorqueSelect3Change = async (value: string) => {
    // 停止之前的轮询
    stopRealDataPolling(3);

    if (value) {
      await callGetDicPropCode(value, 3);
    }
  };

  // 调用getDicPropCode API的函数
  const callGetDicPropCode = async (fieldName: string, chartIndex: number) => {
    try {
      // 解析字段名，例如: 2150_BR1_1_1
      const parts = fieldName.split('_');
      if (parts.length === 4) {
        const [dicLineNo, dicZone, dicRollType, dicRollNo] = parts;

        const params = {
          dicLineNo: dicLineNo,
          dicZone: dicZone,
          dicRollType: dicRollType,
          dicRollNo: dicRollNo,
        };

        console.log('调用getDicPropCode API，参数:', params);
        // 这里需要根据实际的API调用方式进行调整
        // const response = await CAL2150TempCtrlApi.getDicPropCode(params);
        // console.log('getDicPropCode API 响应:', response);

        // 如果API调用成功，继续获取CAL2150_RealData
        // if (response && response.data) {
        //   await fetchCAL2150RealData(response, chartIndex);
        // }
      } else {
        console.log('字段名格式不正确，无法解析:', fieldName);
      }
    } catch (error) {
      console.error('调用getDicPropCode API失败:', error);
    }
  };

  // 开始实时数据轮询
  const startRealDataPolling = (chartIndex: number) => {
    // 先停止之前的轮询
    stopRealDataPolling(chartIndex);

    // 清空之前的数据
    if (chartIndex === 1) {
      realData1.value = [];
    } else if (chartIndex === 2) {
      realData2.value = [];
    } else if (chartIndex === 3) {
      realData3.value = [];
    }

    // 立即执行一次数据获取
    pollRealData(chartIndex);

    // 设置定时器，每秒轮询一次
    const timer = setInterval(() => {
      pollRealData(chartIndex);
    }, 1000);

    // 保存定时器引用
    if (chartIndex === 1) {
      realDataTimer1.value = timer;
    } else if (chartIndex === 2) {
      realDataTimer2.value = timer;
    } else if (chartIndex === 3) {
      realDataTimer3.value = timer;
    }
  };

  // 停止实时数据轮询
  const stopRealDataPolling = (chartIndex: number) => {
    let timer: NodeJS.Timeout | null = null;

    if (chartIndex === 1) {
      timer = realDataTimer1.value;
      realDataTimer1.value = null;
    } else if (chartIndex === 2) {
      timer = realDataTimer2.value;
      realDataTimer2.value = null;
    } else if (chartIndex === 3) {
      timer = realDataTimer3.value;
      realDataTimer3.value = null;
    }

    if (timer) {
      clearInterval(timer);
    }
  };

  // 轮询获取实时数据
  const pollRealData = async (chartIndex: number) => {
    try {
      let dicPropCodes: string[] = [];

      // 获取对应的dicPropCode值
      if (chartIndex === 1) {
        dicPropCodes = currentDicPropCodes1.value;
      } else if (chartIndex === 2) {
        dicPropCodes = currentDicPropCodes2.value;
      } else if (chartIndex === 3) {
        dicPropCodes = currentDicPropCodes3.value;
      }

      if (dicPropCodes.length === 0) {
        return;
      }

      // 调用CAL2150_RealData API
      const realDataResponse = await axios.get('http://10.171.7.100:8090/restapi?name=CAL2150_RealData');

      if (realDataResponse.data) {
        const realData = realDataResponse.data;
        const currentTime = new Date().toLocaleTimeString();
        const values: number[] = [];

        // 遍历dicPropCode值，在realData中查找对应的字段
        dicPropCodes.forEach((propCode: string) => {
          if (realData[propCode] !== undefined) {
            values.push(realData[propCode]);
            console.log(`图表${chartIndex} - 找到字段 ${propCode} 的值:`, realData[propCode]);
          } else {
            values.push(0); // 如果找不到值，设为0
            console.log(`图表${chartIndex} - 未找到字段 ${propCode} 在CAL2150_RealData中`);
          }
        });

        // 保存数据
        const dataPoint = {
          time: currentTime,
          values: values,
        };

        if (chartIndex === 1) {
          realData1.value.push(dataPoint);
          // 保持最近30个数据点
          if (realData1.value.length > 30) {
            realData1.value.shift();
          }
          updateLineChart(1);
        } else if (chartIndex === 2) {
          realData2.value.push(dataPoint);
          if (realData2.value.length > 30) {
            realData2.value.shift();
          }
          updateLineChart(2);
        } else if (chartIndex === 3) {
          realData3.value.push(dataPoint);
          if (realData3.value.length > 30) {
            realData3.value.shift();
          }
          updateLineChart(3);
        }
      }
    } catch (error) {
      console.error(`图表${chartIndex} - 获取CAL2150_RealData失败:`, error);
    }
  };

  // 更新折线图
  const updateLineChart = (chartIndex: number) => {
    let chartInstance: echarts.ECharts | null = null;
    let data: Array<{ time: string; values: number[] }> = [];

    if (chartIndex === 1) {
      chartInstance = lineChart1Instance;
      data = realData1.value;
    } else if (chartIndex === 2) {
      chartInstance = lineChart2Instance;
      data = realData2.value;
    } else if (chartIndex === 3) {
      chartInstance = lineChart3Instance;
      data = realData3.value;
    }

    if (!chartInstance || data.length === 0) {
      return;
    }

    const times = data.map((item) => item.time);

    // 根据新的数据结构创建series
    const seriesNames = ['速度设定mpm', '实际转矩', '速度实际mpm'];
    const colors = ['#5dd1fa', '#91cc75', '#ff6b6b']; // 蓝色、绿色、红色

    const series = seriesNames.map((name, index) => ({
      name: name,
      type: 'line',
      data: data.map((item) => item.values[index] || 0),
      smooth: true,
      lineStyle: {
        width: 2,
        color: colors[index],
      },
      itemStyle: {
        color: colors[index],
      },
      symbol: 'circle',
      symbolSize: 4,
      // 为速度设定mpm和速度实际mpm使用右侧Y轴，实际转矩使用左侧Y轴
      yAxisIndex: index === 1 ? 0 : 1,
    }));

    const option = {
      title: {
        text: ``,
        textStyle: {
          color: '#fff',
          fontSize: 14,
        },
      },
      tooltip: {
        trigger: 'axis',
        backgroundColor: 'rgba(0,0,0,0.9)',
        borderColor: '#42b4ff',
        borderWidth: 1,
        textStyle: {
          color: '#fff',
          fontSize: 12,
        },
        formatter: function (params: any) {
          let result = params[0].axisValue + '<br/>';
          params.forEach((param: any) => {
            // 格式化数值为三位小数
            const value = typeof param.value === 'number' ? param.value.toFixed(3) : param.value;
            result += param.marker + param.seriesName + ': ' + value + '<br/>';
          });
          return result;
        },
      },
      grid: {
        left: '3%',
        right: '4%',
        bottom: '3%',
        containLabel: true,
      },
      xAxis: {
        type: 'category',
        data: times,
        axisLabel: {
          color: '#fff',
        },
        axisLine: {
          lineStyle: {
            color: '#42b4ff',
          },
        },
      },
      yAxis: [
        {
          type: 'value',
          name: '转矩',
          nameTextStyle: {
            color: '#fff',
            fontSize: 12,
          },
          min: 0,
          max: 12000,
          interval: 3000,
          axisLabel: {
            color: '#fff',
          },
          axisLine: {
            lineStyle: {
              color: '#42b4ff',
            },
          },
          splitLine: {
            lineStyle: {
              color: 'rgba(66,180,255,0.3)',
            },
          },
          position: 'left',
        },
        {
          type: 'value',
          name: '速度',
          nameTextStyle: {
            color: '#fff',
            fontSize: 12,
          },
          min: 0,
          max: 1000,
          interval: 200,
          axisLabel: {
            color: '#fff',
          },
          axisLine: {
            lineStyle: {
              color: '#5dd1fa',
            },
          },
          splitLine: {
            show: false,
          },
          position: 'right',
        },
      ],
      series: series,
    };

    chartInstance.setOption(option);
  };

  // --- Table Styles (Adopted from XGRPH.vue) ---
  const rightTableHeaderStyle = {
    background: '#183272', // Darker blue for header
    color: '#b8e8ff',
    padding: '6px 0',
    textAlign: 'center',
    fontWeight: 'normal',
    borderBottom: '1px solid #06279d', // Use the border color from image
  };

  const rightTableCellStyle = {
    padding: '6px 0',
    textAlign: 'center',
    color: '#c0c4cc',
    borderBottom: '1px solid #06279d',
    borderRight: '1px solid #06279d',
    fontSize: '12px',
    // Background will be handled by alternating row styles in CSS
  };

  // --- 生产统计信息 ---
  const productionStats = reactive({
    dailyOutput: 1028.3,
    actualHourlyOutput: 152.5,
    hourlyOutput: 135.0,
    processSpeed: 210.7,
  });

  // --- 张力信息 ---
  const tensionInfo = reactive({
    set: 8.0,
    actual: 2.5,
  });

  // --- 警告信息 ---
  const warningMessage = ref('后卷过度异常, 模型进行了**调整');

  interface TableRow {
    modifyTime: string;
    rollID: string;
    slipReason: number;
    confirmed?: boolean;
  }

  // --- 表格数据 ---
  const tableData = ref<TableRow[]>([
    { modifyTime: '2025-04-01 17: 32: 08', rollID: 'Hooting1 Deflector R1', slipReason: 1, confirmed: false },
    { modifyTime: '2025-04-01 17: 32: 08', rollID: 'Hooting1 Deflector R1', slipReason: 1, confirmed: false },
    { modifyTime: '2025-04-01 17: 32: 08', rollID: 'Hooting1 Deflector R1', slipReason: 1, confirmed: false },
    { modifyTime: '2025-04-01 17: 32: 08', rollID: 'Hooting1 Deflector R1', slipReason: 1, confirmed: false },
    { modifyTime: '2025-04-01 17: 32: 08', rollID: 'Hooting1 Deflector R1', slipReason: 1, confirmed: false },
    { modifyTime: '2025-04-01 17: 32: 08', rollID: 'Hooting1 Deflector R1', slipReason: 1, confirmed: false },
    { modifyTime: '2025-04-01 17: 32: 08', rollID: 'Hooting1 Deflector R1', slipReason: 1, confirmed: false },
    { modifyTime: '2025-04-01 17: 32: 08', rollID: 'Hooting1 Deflector R1', slipReason: 1, confirmed: false },
  ]);

  function confirmRow(index: number) {
    tableData.value[index].confirmed = true;
  }

  // --- 柱状图数据 ---
  const barChartData = {
    超差辊: [35000, 45000, 30000, 45000, 25000, 40000, 35000, 30000],
    公里数: [10000, 30000, 15000, 25000, 20000, 10000, 15000, 20000],
    粗糙度: [15000, 5000, 10000, 5000, 25000, 15000, 10000, 15000],
  };

  // --- 标准值 ---
  const standardValues = {
    超差辊: 32000,
    公里数: 18000,
    粗糙度: 12000,
  };

  // --- 图表配置 ---
  const baseBarOption = {
    tooltip: {
      trigger: 'axis',
      axisPointer: { type: 'shadow' },
      formatter: function (params: any[]) {
        let tooltipText = `${params[0].name}<br/>`;
        params.forEach((param) => {
          tooltipText += `${param.marker}${param.seriesName}: ${param.value}<br/>`;
        });
        return tooltipText;
      },
    },
    grid: { left: '3%', right: '4%', bottom: '3%', top: '15%', containLabel: true },
    legend: {
      data: [] as string[],
      top: '5%',
      textStyle: { color: '#c0c4cc' },
    },
    xAxis: [
      {
        type: 'category',
        data: [] as string[],
        axisTick: { alignWithLabel: true },
        axisLabel: { color: '#c0c4cc', fontSize: 10 },
      },
    ],
    yAxis: [
      {
        type: 'value',
        axisLabel: { color: '#c0c4cc', fontSize: 10 },
        splitLine: { lineStyle: { color: '#3a5a8a', opacity: 0.3 } },
      },
    ],
    series: [] as any[],
  };

  // 柱状图配置
  const statusBarChartOption = computed(() => {
    const currentDataType = barChartType.value as keyof typeof barChartData;
    const actualData = barChartData[currentDataType];
    const stdValue = standardValues[currentDataType];
    const standardData = Array(actualData.length).fill(stdValue);
    const xAxisData = ['R1', 'R3', 'R5', 'R7', 'R9', 'R11', 'R13', 'R15'];

    const series = [
      {
        name: barChartType.value,
        type: 'bar',
        barWidth: '30%',
        data: actualData,
        itemStyle: {
          color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
            { offset: 0, color: barChartType.value === '超差辊' ? '#42b4ff' : barChartType.value === '公里数' ? '#67c23a' : '#e6a23c' },
            { offset: 1, color: 'rgba(11, 41, 96, 0.8)' },
          ]),
          borderRadius: [5, 5, 0, 0],
          shadowColor:
            barChartType.value === '超差辊'
              ? 'rgba(66, 180, 255, 0.5)'
              : barChartType.value === '公里数'
              ? 'rgba(103, 194, 58, 0.5)'
              : 'rgba(230, 162, 60, 0.5)',
          shadowBlur: 10,
        },
      },
      {
        name: '标准值',
        type: 'bar',
        barWidth: '30%',
        data: standardData,
        itemStyle: {
          color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
            { offset: 0, color: '#ff7043' },
            { offset: 1, color: 'rgba(255, 112, 67, 0.5)' },
          ]),
          borderRadius: [5, 5, 0, 0],
          shadowColor: 'rgba(255, 112, 67, 0.5)',
          shadowBlur: 8,
        },
      },
    ];

    return {
      ...baseBarOption,
      legend: {
        ...baseBarOption.legend,
        data: [barChartType.value, '标准值'],
      },
      xAxis: [
        {
          ...baseBarOption.xAxis[0],
          data: xAxisData,
          axisLine: { lineStyle: { color: '#3a5a8a' } },
        },
      ],
      yAxis: [
        {
          ...baseBarOption.yAxis[0],
          axisLine: { lineStyle: { color: '#3a5a8a' } },
          max: 50000,
          interval: 10000,
        },
      ],
      series: series,
    };
  });

  // 更新柱状图
  const updateBarChart = () => {
    if (statusBarChartInstance) {
      const currentDataType = barChartType.value as keyof typeof barChartData;
      const actualData = barChartData[currentDataType];
      const stdValue = standardValues[currentDataType];
      const standardData = Array(actualData.length).fill(stdValue);

      statusBarChartInstance.setOption({
        legend: {
          data: [barChartType.value, '标准值'],
        },
        series: [
          {
            name: barChartType.value,
            data: actualData,
            itemStyle: {
              color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
                { offset: 0, color: barChartType.value === '超差辊' ? '#42b4ff' : barChartType.value === '公里数' ? '#67c23a' : '#e6a23c' },
                { offset: 1, color: 'rgba(11, 41, 96, 0.8)' },
              ]),
              shadowColor:
                barChartType.value === '超差辊'
                  ? 'rgba(66, 180, 255, 0.5)'
                  : barChartType.value === '公里数'
                  ? 'rgba(103, 194, 58, 0.5)'
                  : 'rgba(230, 162, 60, 0.5)',
            },
          },
          {
            name: '标准值',
            data: standardData,
          },
        ],
      });
    }
  };

  // 线图配置 - 与图片匹配的数据和样式
  const lineChartOption1 = computed(() => ({
    backgroundColor: 'transparent',
    tooltip: { trigger: 'axis' },
    legend: {
      data: ['指标A', '指标B'],
      textStyle: { color: '#fff', fontSize: 12 },
      formatter: function (name: string) {
        return name === '指标A' ? '指标A' : '指标B';
      },
      selectedMode: false,
      icon: 'circle',
      itemWidth: 8,
      itemHeight: 8,
      top: '5%',
      itemGap: 20,
    },
    grid: {
      left: '5%',
      right: '5%',
      bottom: '10%',
      top: '25%',
      containLabel: true,
    },
    xAxis: {
      type: 'category',
      boundaryGap: false,
      data: ['T0', 'T1', 'T2', 'T3', 'T4', 'T5', 'T6', 'T7', 'T8', 'T9'],
      axisLine: { lineStyle: { color: '#3a5a8a' } },
      axisLabel: { color: '#c0c4cc', fontSize: 10 },
      splitLine: { show: false },
    },
    yAxis: {
      type: 'value',
      min: 0,
      max: 8,
      interval: 2,
      axisLabel: { color: '#c0c4cc', fontSize: 10 },
      splitLine: { lineStyle: { color: '#3a5a8a', opacity: 0.3 } },
      axisLine: { lineStyle: { color: '#3a5a8a' } },
    },
    series: [
      {
        name: '指标A',
        type: 'line',
        smooth: true,
        symbolSize: 6,
        symbol: 'circle',
        areaStyle: {
          opacity: 0.8,
          color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
            { offset: 0, color: 'rgba(58, 218, 255, 0.8)' },
            { offset: 1, color: 'rgba(11, 41, 96, 0.1)' },
          ]),
        },
        emphasis: { focus: 'series' },
        data: [5.2, 4.1, 4.3, 4.8, 4.2, 4.7, 5.5, 6.0, 5.2, 4.0],
        itemStyle: {
          color: '#5dd1fa',
          shadowColor: 'rgba(93, 209, 250, 0.8)',
          shadowBlur: 10,
        },
        lineStyle: {
          width: 3,
          shadowColor: 'rgba(93, 209, 250, 0.8)',
          shadowBlur: 10,
        },
      },
      {
        name: '指标B',
        type: 'line',
        smooth: true,
        symbolSize: 6,
        symbol: 'circle',
        areaStyle: {
          opacity: 0.4,
          color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
            { offset: 0, color: 'rgba(150, 220, 90, 0.6)' },
            { offset: 1, color: 'rgba(11, 41, 96, 0.1)' },
          ]),
        },
        emphasis: { focus: 'series' },
        data: [3.0, 2.1, 3.5, 4.0, 2.8, 2.1, 1.5, 2.3, 2.0, 1.8],
        itemStyle: {
          color: '#91cc75',
          shadowColor: 'rgba(145, 204, 117, 0.8)',
          shadowBlur: 10,
        },
        lineStyle: {
          width: 3,
          type: 'dashed',
          shadowColor: 'rgba(145, 204, 117, 0.8)',
          shadowBlur: 5,
        },
      },
    ],
  }));

  const baseLineOption = {
    tooltip: { trigger: 'axis' },
    legend: {
      data: [] as string[],
      textStyle: { color: '#c0c4cc' },
      icon: 'circle',
      itemWidth: 8,
      itemHeight: 8,
      top: '5%',
      itemGap: 20,
    },
    grid: { left: '5%', right: '5%', bottom: '10%', top: '25%', containLabel: true },
    xAxis: {
      type: 'category',
      boundaryGap: false,
      data: [] as string[],
      axisLabel: { color: '#c0c4cc', fontSize: 10 },
      splitLine: { show: false },
    },
    yAxis: {
      type: 'value',
      axisLabel: { color: '#c0c4cc', fontSize: 10 },
      splitLine: { lineStyle: { color: '#3a5a8a', opacity: 0.3 } },
      min: 0,
      max: 8,
    },
    series: [] as any[],
  };

  // --- SVG交互 ---
  const onSvgLoaded = () => {
    console.log('SVG图片加载完成');

    // 简化SVG加载事件，暂时移除SVG DOM操作
    try {
      // SVG加载成功
      console.log('SVG加载成功');
    } catch (error) {
      console.error('SVG操作失败:', error);
    }
  };

  // --- 初始化图表 ---
  const initCharts = () => {
    try {
      if (statusBarChartRef.value && !statusBarChartInstance) {
        statusBarChartInstance = echarts.init(statusBarChartRef.value);
        statusBarChartInstance.setOption(statusBarChartOption.value);
      }

      const lineChartOption = lineChartOption1.value;

      if (lineChart1Ref.value && !lineChart1Instance) {
        lineChart1Instance = echarts.init(lineChart1Ref.value);
        lineChart1Instance.setOption(lineChartOption);
      }
      if (lineChart2Ref.value && !lineChart2Instance) {
        lineChart2Instance = echarts.init(lineChart2Ref.value);
        lineChart2Instance.setOption(lineChartOption);
      }
      if (lineChart3Ref.value && !lineChart3Instance) {
        lineChart3Instance = echarts.init(lineChart3Ref.value);
        lineChart3Instance.setOption(lineChartOption);
      }
    } catch (error) {
      console.error('图表初始化失败:', error);
    }
  };

  // 动态更新数据
  const updateData = () => {
    // 更新生产统计信息（小幅度波动）
    productionStats.dailyOutput = parseFloat((1028.3 + (Math.random() * 10 - 5)).toFixed(1));
    productionStats.actualHourlyOutput = parseFloat((152.5 + (Math.random() * 5 - 2.5)).toFixed(1));
    productionStats.hourlyOutput = parseFloat((135.0 + (Math.random() * 4 - 2)).toFixed(1));
    productionStats.processSpeed = parseFloat((210.7 + (Math.random() * 8 - 4)).toFixed(1));

    // 更新张力信息（小幅度波动）
    tensionInfo.actual = parseFloat((2.5 + (Math.random() * 0.6 - 0.3)).toFixed(1));
  };

  const resizeCharts = () => {
    statusBarChartInstance?.resize();
    lineChart1Instance?.resize();
    lineChart2Instance?.resize();
    lineChart3Instance?.resize();
  };

  // --- 生命周期钩子 ---
  let updateTimer: number | null = null;

  // Refs for ZLGDH specific live data (similar to continuousrefund/index.vue)
  const zlgdhEntSpeed = ref<number>(0);
  const zlgdhProcessSpeed = ref<number>(0);
  const zlgdhExitSpeed = ref<number>(0);

  const zlgdhInletLooper = ref<number>(0);
  const zlgdhMiddleLooper = ref<number>(0);
  const zlgdhExportLooper = ref<number>(0);

  const zlgdhInletLooperTime = ref<string>('0 min');
  const zlgdhMiddleLooperTime = ref<string>('0 min');
  const zlgdhExportLooperTime = ref<string>('0 min');

  const zlgdhUncoilerLenA = ref<number>(0);
  const zlgdhUncoilerLenB = ref<number>(0);
  const zlgdhCoilerLenA = ref<number>(0);
  const zlgdhCoilerLenB = ref<number>(0);

  const zlgdhCpcWidth = ref<number>(0);
  const zlgdhCpcWidthAlarm = ref<boolean>(false);

  let tr: any = null;
  let por: any = null;
  let ti: any = null;

  let interval: any = null;
  const inletLooper = ref<number>(0);
  const middleLooper = ref<number>(0);
  const exportLooper = ref<number>(0);

  // Refs for ZLGDH speed chart instances
  let zlgdhSpeedChartEntInstance: echarts.ECharts | null = null;
  let zlgdhSpeedChartProcessInstance: echarts.ECharts | null = null;
  let zlgdhSpeedChartExitInstance: echarts.ECharts | null = null;

  // Base options for ZLGDH speed gauges (adapt from continuousrefund)
  const ZlgdhSpeedBaseOption: any = {
    ent: { max: 300, segmentation1: 80, segmentation2: 180 }, // Example values, adjust as needed
    process: { max: 300, segmentation1: 80, segmentation2: 180 },
    exit: { max: 300, segmentation1: 80, segmentation2: 180 },
  };

  const numberFormat = (number: any, precision: number = 0) => {
    if (number === undefined || number === null || String(number).trim() === '') {
      const zero = 0;
      return zero.toFixed(precision);
    }
    const num = parseFloat(String(number));
    if (isNaN(num)) {
      const zero = 0;
      return zero.toFixed(precision);
    }
    return num.toFixed(precision);
  };

  const sleeveDeclineTime = (
    unitName: string,
    position: 'entrance' | 'middle' | 'exit',
    speed1: number,
    speed2: number,
    loopValue: number // Assuming loopValue is already 0-100 range from API (e.g. 50.75 for 50.75%)
  ): string => {
    console.warn('sleeveDeclineTime function is a placeholder. You MUST replace this with the actual function from CAL2150Track.vue.');
    // Example: if loopValue is 50 (for 50%), and speed diff is 10 m/min
    // This placeholder is extremely basic and likely incorrect for your needs.
    const loopLengthFactor = 0.2; // Example: 1% of loop = 0.2 meters. This needs to be accurate for CAL2150.
    const effectiveLoopLength = loopValue * loopLengthFactor;
    const speedDiffMps = Math.abs(speed1 - speed2) / 60; // m/min to m/s
    let timeInSeconds = 0;
    if (speedDiffMps > 0.01) {
      timeInSeconds = effectiveLoopLength / speedDiffMps;
    }
    if (timeInSeconds > 3600) return '>1h';
    if (timeInSeconds > 60) return (timeInSeconds / 60).toFixed(1) + ' min';
    return timeInSeconds.toFixed(1) + ' s';
  };

  const initZlgdhScoreChart = (chartId: string, value: number, type: 'ent' | 'process' | 'exit') => {
    const chartDom = document.getElementById(chartId) as HTMLElement;
    if (!chartDom) return null;

    let speedChart = echarts.getInstanceByDom(chartDom);
    if (!speedChart) {
      speedChart = echarts.init(chartDom);
    }
    const baseOption = ZlgdhSpeedBaseOption[type];
    const option = {
      series: [
        {
          type: 'gauge',
          center: ['50%', '50%'],
          radius: '85%',
          startAngle: 225,
          endAngle: -45,
          max: baseOption.max,
          axisLine: {
            roundCap: true,
            lineStyle: {
              width: 7,
              color: [
                [
                  1,
                  new echarts.graphic.LinearGradient(0, 1, 0.9, 1, [
                    { offset: 0, color: '#D64444' },
                    { offset: 0.2, color: '#D86E6D' },
                    { offset: 0.5, color: '#F1F3F4' },
                    { offset: 0.65, color: '#F1F3F4' },
                    { offset: 0.8, color: '#79ACF6' },
                    { offset: 1, color: '#1976FD' },
                  ]),
                ],
              ],
            },
          },
          pointer: { length: '80%', width: 2, color: '#FFFFFF' },
          axisTick: { distance: -10, length: 2, lineStyle: { color: '#4B83F7', width: 1 } },
          splitLine: { distance: -12, length: 4, lineStyle: { color: '#4B83F7', width: 1 } },
          axisLabel: { show: false },
          title: {
            offsetCenter: [0, '70%'],
            fontSize: 10,
            color: '#FFF',
          },
          detail: {
            fontSize: 14,
            offsetCenter: [0, '30%'],
            valueAnimation: true,
            formatter: function (value: any) {
              return `${parseFloat(String(value)).toFixed(0)}`;
            },
            color: '#FFF',
          },
          data: [{ value: value, name: 'mpm' }],
        },
      ],
    };
    speedChart.setOption(option);
    return speedChart;
  };

  // Main function to fetch and process all live data
  const updateZlgdhLiveData = async () => {
    try {
      // 1. Fetch ItemTag Data (G_...NI values)
      const itemTagResponse = await axios.get('http://10.171.7.100:8090/restapi?name=CAL2150_itemtag');
      itemTagData.value = itemTagResponse.data || {};
      const currentItemTags = itemTagData.value;

      // Update refs from itemTagData (mirroring CAL2150Track.vue's getItemTag function)
      zlgdhEntSpeed.value = parseFloat(String(currentItemTags['G1_1803NI'] || '0'));
      zlgdhProcessSpeed.value = parseFloat(String(currentItemTags['G1_1801NI'] || '0')); // CAL2150Track uses G1_1801NI for spmSpeed
      zlgdhExitSpeed.value = parseFloat(String(currentItemTags['G1_1800NI'] || '0'));
      // let cenSpeed = parseFloat(String(currentItemTags['G1_1802NI'] || '0')); // CAL2150Track cenSpeed, if needed for ZLGDH logic

      zlgdhUncoilerLenA.value = parseFloat(String(currentItemTags['G201_529NI'] || '0'));
      zlgdhUncoilerLenB.value = parseFloat(String(currentItemTags['G201_536NI'] || '0'));
      zlgdhCoilerLenA.value = parseFloat(String(currentItemTags['G414_448NI'] || '0'));
      zlgdhCoilerLenB.value = parseFloat(String(currentItemTags['G414_457NI'] || '0'));
      zlgdhCpcWidth.value = parseFloat(String(currentItemTags['G17_405NI'] || '0'));
      // TODO: zlgdhCpcWidthAlarm logic - CAL2150Track derives this from PDI (zone18SetWidth). This needs adaptation if required.
      // zlgdhCpcWidthAlarm.value = zlgdhCpcWidth.value - 4 - 20 < zone18SetWidth.value + 4;

      // 2. Fetch ZoneTrack Data (zones, loop, tr, por, weld)
      const zoneTrackResponse = await axios.get('http://10.171.7.100:8090/restapi?name=CAL2150_zonetrk');
      zoneTrackData.value = zoneTrackResponse.data || {};
      const currentZoneTracks = zoneTrackData.value;

      if (currentZoneTracks.loop && currentZoneTracks.loop.length >= 3) {
        // Assuming API returns direct percentage values (e.g., 50.75 for 50.75%) OR values that need /100.
        // CAL2150Track.vue divides by 100 when displaying, implying API might send 5075.
        // User wants API 5075 to mean 0.5075 internally, displayed as 51% or 50%.
        // So, divide by 10000 to get 0.xxxx form, then multiply by 100 in template and format to 0 decimals.
        const factor = 10000; // If API sends 5075 for what should be 0.5075 internally.
        zlgdhInletLooper.value = parseFloat(String(currentZoneTracks.loop[2] || '0')) / factor; // Template: 入口活套, CAL2150 map: exitLooper = loop[2]
        zlgdhMiddleLooper.value = parseFloat(String(currentZoneTracks.loop[1] || '0')) / factor; // Template: 中间活套, CAL2150 map: middleLooper = loop[1]
        zlgdhExportLooper.value = parseFloat(String(currentZoneTracks.loop[0] || '0')) / factor; // Template: 出口活套, CAL2150 map: inletLooper = loop[0]
        // Note: The variable names zlgdhInletLooper and zlgdhExportLooper might be swapped compared to their physical location labels in the template.
        // currentZoneTracks.loop[0] is usually Entrance, loop[1] Middle, loop[2] Exit.
        // Your template labels: zlgdhInletLooper = "入口活套", zlgdhExportLooper = "出口活套"
        // This mapping assumes currentZoneTracks.loop[0] maps to your zlgdhExportLooper (入口), and loop[2] to zlgdhInletLooper (出口).
      }

      // Calculate Looper Times (now that speeds and loop values are available)
      // These speed parameters to sleeveDeclineTime match CAL2150Track.vue's getItemTag usage
      // IMPORTANT: sleeveDeclineTime expects loopValue as 0-100 percentage. We now have 0.xxxx in zlgdh...Looper refs.
      zlgdhInletLooperTime.value = sleeveDeclineTime(
        technologicalName,
        'entrance',
        zlgdhEntSpeed.value,
        zlgdhProcessSpeed.value,
        zlgdhInletLooper.value * 100
      );
      zlgdhMiddleLooperTime.value = sleeveDeclineTime(
        technologicalName,
        'middle',
        zlgdhProcessSpeed.value,
        zlgdhExitSpeed.value,
        zlgdhMiddleLooper.value * 100
      );
      zlgdhExportLooperTime.value = sleeveDeclineTime(
        technologicalName,
        'exit',
        zlgdhProcessSpeed.value,
        zlgdhExitSpeed.value,
        zlgdhExportLooper.value * 100
      );

      // Update ECharts speed gauges with new values
      if (zlgdhSpeedChartEntInstance) zlgdhSpeedChartEntInstance.setOption({ series: [{ data: [{ value: zlgdhEntSpeed.value }] }] });
      if (zlgdhSpeedChartProcessInstance) zlgdhSpeedChartProcessInstance.setOption({ series: [{ data: [{ value: zlgdhProcessSpeed.value }] }] });
      if (zlgdhSpeedChartExitInstance) zlgdhSpeedChartExitInstance.setOption({ series: [{ data: [{ value: zlgdhExitSpeed.value }] }] });
    } catch (error) {
      console.error('Error in updateZlgdhLiveData:', error);
    }

    // Update other existing data (for top panel charts, if any specific logic beyond direct binding was here)
    updateData();
  };

  onBeforeMount(() => {
    interval = setInterval(() => {
      getZoneTrk();
    }, 2000);
  });

  const getZoneTrk = async () => {
    let param = {
      name: 'CAL2150_zonetrk',
    };
    rollingSimulationApi.rest(param).then((res) => {
      let zones = res.data.zoneno;
      // weldMachineState(`${technologicalName}-welder`, res.weld)
      inletLooper.value = res.data['loop'][0];
      middleLooper.value = res.data['loop'][1];
      exportLooper.value = res.data['loop'][2];
      let trKey = `${technologicalName}-ZONE_tr${res.data.tr}`;
      let trpathKey = trKey + '_path';
      let porKey = `${technologicalName}-ZONE_por${res.data.por}`;
      let porpathKey = porKey + '_path';
      var arr = Object.keys(zones);
      /**开卷机和卷取机 */
      if (tr === null || tr !== res.data.tr) {
        tr = res.data.tr;
        refreshSVG(zones[arr.length - 1].ti % 10, trpathKey);
        refreshGraphical(zones[arr.length - 1].ti % 10, trKey);
        initialSVG(technologicalName, 'tr', res.data.tr);
      }
      if (por === null || por !== res.data.por) {
        por = res.data.por;
        if (res.data.por === 0) {
          initialSVG(technologicalName, 'por', '1');
          initialSVG(technologicalName, 'por', '2');
        }
      }
      if (ti === null || ti !== zones[0].ti) {
        ti = zones[0].ti;
        refreshSVG(zones[0].ti % 10, porpathKey);
        refreshGraphical(zones[0].ti % 10, porKey);
        initialSVG(technologicalName, 'por', res.data.por);
      }
      for (let i in zones) {
        let pathkey = `${technologicalName}-ZONE${i}`;
        console.log(pathkey);
        refreshSVG(zones[i].ti % 10, pathkey);
      }
    });
  };

  onMounted(() => {
    nextTick(() => {
      setTimeout(() => {
        initCharts(); // Existing charts for top panel

        // Initialize ZLGDH speed gauges
        zlgdhSpeedChartEntInstance = initZlgdhScoreChart('zlgdh_speed_ent', zlgdhEntSpeed.value, 'ent');
        zlgdhSpeedChartProcessInstance = initZlgdhScoreChart('zlgdh_speed_process', zlgdhProcessSpeed.value, 'process');
        zlgdhSpeedChartExitInstance = initZlgdhScoreChart('zlgdh_speed_exit', zlgdhExitSpeed.value, 'exit');

        // Initial fetch and update of all live data
        updateZlgdhLiveData();
        // Removed previous direct axios.get for itemtag/zonetrk as they are now inside updateZlgdhLiveData
      }, 100);
    });

    window.addEventListener('resize', () => {
      resizeCharts(); // Resize top panel charts
      zlgdhSpeedChartEntInstance?.resize();
      zlgdhSpeedChartProcessInstance?.resize();
      zlgdhSpeedChartExitInstance?.resize();
    });

    // Set up periodic updates
    updateTimer = window.setInterval(updateZlgdhLiveData, 3000);
  });

  onUnmounted(() => {
    window.removeEventListener('resize', resizeCharts);
    statusBarChartInstance?.dispose();
    lineChart1Instance?.dispose();
    lineChart2Instance?.dispose();
    lineChart3Instance?.dispose();

    zlgdhSpeedChartEntInstance?.dispose();
    zlgdhSpeedChartProcessInstance?.dispose();
    zlgdhSpeedChartExitInstance?.dispose();

    if (updateTimer !== null) {
      clearInterval(updateTimer);
    }
    if (interval !== null) {
      clearInterval(interval);
    }
  });

  // --- API data storage and SVG state tracking (as per CAL2150Track.vue logic) ---
  const itemTagData = ref<any>({});
  const zoneTrackData = ref<any>({});
  const technologicalName = 'CAL2150';

  let prevTr: string | null = null;
  let prevPor: string | null = null;
  let prevTi: string | null = null;
</script>

<style scoped lang="less">
  .cgl-container {
    position: relative;
    background: url('../../assets/images/body-bg.jpg') no-repeat center center;
    background-size: cover;
    height: 100vh;
    width: 100%;
    overflow: hidden;
    color: #fff;
    padding: 0;
    margin: 0;
    box-sizing: border-box;
    font-family: 'Microsoft YaHei', Arial, sans-serif;
    display: flex;
    flex-direction: column;
  }

  /* 头部样式 */
  .header {
    flex: 0 0 60px;
    background-image: url('../../assets/images/head-bg.png');
    background-size: 100% 100%;
    background-repeat: no-repeat;
    display: flex;
    align-items: flex-start;
    justify-content: center;
    position: relative;
    z-index: 10;
    padding-top: 3px;
    margin-bottom: -15px;
  }

  .titleMain {
    font-size: 20px;
    color: #ffffff;
    text-align: center;
    text-shadow:
      0 0 10px #42b4ff,
      0 0 20px #0a2466;
    letter-spacing: 2px;
  }

  /* Top Charts Panel */
  .top-charts-panel {
    display: flex;
    margin: 0 5px;
    height: 190px;
    flex-shrink: 0;
    position: relative;
    z-index: 20;
  }

  .chart-card {
    /* background-image: url('../../assets/img/itme_bg.png'); */ /* 移除背景图 */
    /* background-size: cover; */
    /* background-position: center; */
    background-color: rgba(28, 58, 99, 0.7); /* 设置半透明背景色 */
    border: 1px solid rgba(90, 130, 190, 0.4);
    border-radius: 0;
    display: flex;
    flex-direction: column;
    overflow: hidden;
    position: relative;
    margin-right: 5px;
    box-shadow: 0 0 15px rgba(11, 93, 209, 0.2);
  }

  .chart-card:last-child {
    margin-right: 0;
  }

  .status-chart {
    flex: 1.5;
  }
  .line-chart {
    flex: 1;
  }

  .chart-header {
    background-image: url('../../assets/img/sub_title_bg.png');
    background-size: 100% 100%;
    background-repeat: no-repeat;
    position: relative;
    height: 30px;
    width: 100%;
    border-bottom: 1px solid rgba(58, 90, 138, 0.6);
    display: flex;
    justify-content: space-between;
    align-items: center;
  }

  .title-bar {
    display: flex;
    align-items: center;
    padding-left: 10px;
  }

  .blue-bar {
    display: inline-block;
    width: 3px;
    height: 16px;
    background-color: #42b4ff;
    margin-right: 8px;
    box-shadow: 0 0 8px #42b4ff;
  }

  .title-text {
    font-size: 13px;
    font-weight: bold;
    color: #a2dfff;
    text-shadow: 0 0 5px rgba(66, 180, 255, 0.5);
  }

  .chart-buttons {
    padding-right: 10px;
  }

  :deep(.el-radio-button__inner) {
    background-color: transparent;
    border: none;
    color: #a0a3a8;
    padding: 4px 8px;
    font-size: 12px;
    height: 24px;
    line-height: 16px;
  }

  :deep(.el-radio-button__orig-radio:checked + .el-radio-button__inner) {
    color: #42b4ff;
    border-bottom: 2px solid #42b4ff;
    background-color: transparent;
    box-shadow: none;
    text-shadow: 0 0 5px #42b4ff;
  }

  :deep(.el-radio-button:first-child .el-radio-button__inner),
  :deep(.el-radio-button:last-child .el-radio-button__inner) {
    border-radius: 0px;
  }

  .chart-controls {
    padding-right: 10px;
  }

  /* 深度选择器修改 el-select 内部元素的样式 */
  :deep(.torque-select .el-select__wrapper) {
    background-color: rgba(41, 121, 255, 0.2) !important;
    border: 1px solid #42b4ff !important;
    box-shadow: 0 0 8px rgba(41, 121, 255, 0.5) !important;
    height: 22px !important;
    width: 110px;
  }

  :deep(.torque-select .el-input__inner) {
    height: 20px !important;
    line-height: 20px !important;
    font-size: 11px !important;
    color: #fff !important;
    padding: 0 10px;
  }

  :deep(.torque-select .el-select__caret) {
    font-size: 11px !important;
    color: #42b4ff;
  }

  :deep(.torque-select .el-select__placeholder) {
    font-size: 11px !important;
    color: #a0a3a8;
  }

  .chart-content {
    flex-grow: 1;
    width: 100%;
    height: calc(100% - 30px);
  }

  /* Process Stats Panel */
  .process-stats-panel {
    flex-grow: 1;
    margin: 10px 5px 5px;
    position: relative;
    /* background-image: url('../../assets/svgs/CAL2150.svg'); */
    background-size: 100% 100%;
    background-position: center;
    background-repeat: no-repeat;
    min-height: 250px;

    .roll-pos-image-block {
      position: absolute;
      top: 0;
      height: 100%;
    }

    .roll-pos-image-block:nth-child(1) {
      left: 0;
      width: 29%;
    }

    .roll-pos-image-block:nth-child(2) {
      left: 29%;
      width: 36%;
    }

    .roll-pos-image-block:nth-child(3) {
      right: 0;
      width: 35%;
    }

    .svg {
      width: 100%;
      height: 100%;

      svg {
        width: 100%;
        height: 100%;
      }
    }
  }

  .process-diagram {
    position: relative;
    width: 100%;
    height: 100%;
  }

  .stats-overlay-container {
    position: absolute;
    bottom: 330px;
    left: 0;
    width: 100%;
    display: flex;
    justify-content: space-around;
    padding: 0 4%;
    z-index: 5;
  }

  .stat-card {
    position: relative;
    width: 100px;
    height: 40px;
    border-radius: 8px;
    //overflow: hidden;
    transition:
      transform 0.3s ease,
      box-shadow 0.3s ease;
    backdrop-filter: blur(3px);
  }

  .stat-card:hover {
    transform: translateY(-5px);
    box-shadow: 0 8px 25px rgba(66, 180, 255, 0.4);
  }

  .stat-card::before {
    content: '';
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    background: url('../../assets/img/zl-pic52.png') center bottom no-repeat;
    background-size: contain;
    z-index: 0;
    border-radius: 8px;
    filter: brightness(1.2);
  }

  .stat-card-content {
    position: relative;
    z-index: 1;
    height: 100%;
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    padding: 10px;
    clip-path: polygon(0 0, 100% 0, 100% 88%, 88% 100%, 0 100%);
  }

  .stat-title {
    font-size: 13px;
    color: #a2cfff;
    margin-bottom: 8px;
    text-shadow: 0 0 5px rgba(100, 180, 255, 0.7);
    font-weight: 500;
  }

  .stat-value {
    font-size: 13px;
    font-weight: bold;
    color: #fff;
    text-shadow: 0 0 8px rgba(100, 180, 255, 0.8);
    line-height: 1.2;
  }

  .stat3 {
    position: relative;
    right: 2%;
  }

  .stat4 {
    position: relative;
    left: 4%;
  }

  .stat-value .unit {
    font-size: 13px;
    font-weight: normal;
    opacity: 0.8;
    margin-left: 3px;
  }

  .stat-icon {
    position: absolute;
    top: 12px;
    right: 12px;
    width: 28px;
    height: 28px;
    background: rgba(66, 180, 255, 0.15);
    border-radius: 50%;
    display: flex;
    justify-content: center;
    align-items: center;
    box-shadow: 0 0 8px rgba(66, 180, 255, 0.4);
    animation: rotate-icon 12s infinite linear;
  }

  @keyframes rotate-icon {
    0% {
      transform: rotate(0deg);
    }
    100% {
      transform: rotate(360deg);
    }
  }

  .stat-icon i {
    font-size: 15px;
    color: #6dc7ff;
  }

  .stat-card-glow {
    position: absolute;
    bottom: -5px;
    left: 50%;
    transform: translateX(-50%);
    width: 75%;
    height: 8px;
    background: rgba(66, 180, 255, 0.7);
    border-radius: 50%;
    filter: blur(7px);
    animation: glow 2.5s infinite alternate;
    z-index: 0;
  }

  @keyframes glow {
    0% {
      opacity: 0.4;
      width: 65%;
    }
    100% {
      opacity: 0.8;
      width: 75%;
    }
  }

  .tension-info {
    position: absolute;
    top: 3px;
    right: 10px;
    font-size: 12px;
    color: #c0c4cc;
  }

  .tension-info strong {
    color: #fff;
    font-weight: bold;
    text-shadow: 0 0 5px rgba(41, 121, 255, 0.7);
  }

  /* Warning Banner */
  .warning-banner {
    width: 400px;
    background-color: rgba(255, 77, 79, 0.8);
    color: #fff;
    padding: 4px 15px;
    margin: 0 5px 5px;
    font-size: 13px;
    text-align: center;
    flex-shrink: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    border: 1px solid #ea0f0f;
    box-shadow: 0 0 10px rgba(255, 77, 79, 0.5);
    animation: flash 2s infinite;
  }

  .warning-banner i {
    margin-right: 8px;
    color: #fff;
  }

  /* Bottom Panel Styles */
  .bottom-panel {
    padding: 5px;
    flex-shrink: 0;
    height: 190px;
  }

  /* Wrapper for the two table cards */
  .tables-wrapper {
    display: flex;
    height: 100%;
    gap: 5px;
  }

  /* General Table Card Style */
  .table-card {
    display: flex;
    flex-direction: column;
    background-color: rgba(28, 58, 99, 0.7);
    border: 1px solid rgba(90, 130, 190, 0.4);
    box-shadow: 0 0 15px rgba(11, 93, 209, 0.2);
    overflow: hidden;
  }

  /* Style for left table card */
  .left-table-card {
    flex-shrink: 0;
    width: 100%;
  }

  /* Style for right table card */
  .right-table-card {
    flex-grow: 1;
  }

  /* Card Header Style (similar to chart headers) */
  .card-header {
    background-image: url('../../assets/img/sub_title_bg.png');
    background-size: 100% 100%;
    background-repeat: no-repeat;
    padding: 6px 15px;
    font-weight: bold;
    flex-shrink: 0;
    border-bottom: 1px solid rgba(58, 90, 138, 0.6);
    display: flex;
    align-items: center;
    justify-content: center;
    height: 3.5vh;
    line-height: 3.5vh;
  }

  /* Style for the title text span */
  .card-header span {
    background-image: -webkit-linear-gradient(left, #0072ff, #00eaff, #01aaff);
    -webkit-background-clip: text;
    background-clip: text;
    -webkit-text-fill-color: transparent;
    font-weight: bolder;
    font-size: 1.7vh;
  }

  /* Copied Icon Styles from NewCoilCard */
  .title-icon-left {
    margin-right: 1vw;
    transform: rotateY(180deg);
    width: 2vw;
    height: 3vh;
    background-image: url(/src/assets/images/title-icon-right.png);
    background-size: 100% 100%;
  }

  .title-icon-right {
    margin-left: 1vw;
    width: 2vw;
    height: 3vh;
    background-image: url(/src/assets/images/title-icon-right.png);
    background-size: 100% 100%;
  }

  /* Ensure tables fill the card content area */
  .left-table,
  .right-table {
    flex-grow: 1;
    width: 100% !important;
    height: 100% !important;
    background-color: transparent !important;
    border: none !important;
  }

  /* Deep Table Styles from XGRPH.vue */
  :deep(.el-table) {
    background-color: transparent !important;
    border: none !important;
  }

  :deep(.el-table tr:nth-child(odd)) {
    background-color: #0f2142 !important;
  }

  :deep(.el-table tr:nth-child(even)) {
    background-color: #142a52 !important;
  }

  :deep(.el-table--enable-row-hover .el-table__body tr:hover > td.el-table__cell) {
    background-color: rgba(66, 180, 255, 0.1) !important;
  }

  :deep(.el-table td.el-table__cell),
  :deep(.el-table th.el-table__cell) {
    background-color: transparent !important;
    border-color: #06279d !important;
    color: #c0c4cc;
  }

  :deep(.el-table th.el-table__cell) {
    color: #b8e8ff;
    background-color: #183272 !important;
    border-bottom: 1px solid #06279d !important;
  }

  :deep(.el-table--border .el-table__inner-wrapper::after),
  :deep(.el-table--border::after),
  :deep(.el-table--border::before),
  :deep(.el-table__border-left-patch),
  :deep(.el-table--border .el-table__inner-wrapper::before) {
    background-color: #06279d !important;
  }

  :deep(.el-table td.el-table__cell),
  :deep(.el-table th.el-table__cell.is-leaf) {
    border-bottom: 1px solid #06279d !important;
  }

  :deep(.el-table--border td.el-table__cell),
  :deep(.el-table--border th.el-table__cell) {
    border-right: 1px solid #06279d !important;
  }

  :deep(.el-table__body-wrapper) {
    scrollbar-width: thin;
    scrollbar-color: #3a5a8a #142a52;
  }

  :deep(.el-table__body-wrapper::-webkit-scrollbar) {
    width: 6px;
    height: 6px;
  }

  :deep(.el-table__body-wrapper::-webkit-scrollbar-track) {
    background: #142a52;
    border-radius: 3px;
  }

  :deep(.el-table__body-wrapper::-webkit-scrollbar-thumb) {
    background-color: #3a5a8a;
    border-radius: 3px;
  }

  @keyframes flash {
    0%,
    100% {
      opacity: 1;
    }
    50% {
      opacity: 0.7;
    }
  }

  @keyframes glow {
    0%,
    100% {
      filter: brightness(1);
    }
    50% {
      filter: brightness(1.3);
    }
  }

  /* Styles for newly added ZLGDH data display */
  .zlgdh-added-data-layer {
    /* This layer itself might not need specific positioning if its children are all absolute */
    /* position: absolute; */ /* Potentially remove if .process-stats-panel is the main relative parent */
    /* top: 0; left: 0; right: 0; bottom: 0; */ /* Make it cover the parent if needed */
    /* z-index: 15; */
    /* display: flex; */ /* Remove flex if children are absolute */
    /* flex-direction: column; */
    /* gap: 5px; */
  }

  /* Remove .zlgdh-gauge-row and .zlgdh-live-data-row styling as they are removed from HTML */

  .gauge-wrapper {
    position: absolute; /* Key for precise placement */
    display: flex;
    flex-direction: column;
    align-items: center;
    padding: 5px;
    z-index: 20; /* Ensure gauges are above the data layer background if any */
  }

  .gauge-title {
    font-size: 11px;
    color: #a2dfff;
    margin-bottom: 2px; /* Reduced margin */
  }

  .gauge-container {
    width: 90px; /* Slightly smaller default */
    height: 90px; /* Slightly smaller default */
  }

  /* START: Precise positioning examples - YOU NEED TO ADJUST THESE VALUES */
  .zlgdh-gauge-ent {
    top: 18%; /* Example value */
    left: 5%; /* Example value */
  }

  .zlgdh-gauge-process {
    top: 15%; /* Example value */
    right: 20%; /* Example value */
    transform: translateX(-50%); /* Center if using left: 50% */
  }

  .zlgdh-gauge-exit {
    top: 15%; /* Example value */
    right: 17%; /* Example value */
  }

  /* Styling for individual data boxes, now absolutely positioned */
  .semitransp_box {
    position: absolute; /* Key for precise placement */
    background: rgba(6, 62, 144, 0.75);
    color: #fff;
    padding: 3px 6px; /* Slightly smaller padding */
    border-radius: 3px;
    font-size: 10px; /* Smaller font */
    text-align: center;
    border: 1px solid rgba(66, 180, 255, 0.35);
    z-index: 20;
    min-width: 100px; /* Ensure some minimum width */
  }
  .semitransp_box p {
    margin: 0 2px;
    display: block; /* Change to block for title and value on separate lines */
    line-height: 1.3; /* Adjust line height */
  }
  .semitransp_box p:first-child {
    font-weight: normal;
    opacity: 0.8;
    font-size: 9px; /* Smaller title font */
  }
  .semitransp_box p:last-child {
    font-weight: bold;
    font-size: 11px; /* Value font size */
  }

  /* Example positioning for data boxes - YOU NEED TO ADJUST THESE */
  .zlgdh_inlet_looper {
    top: 17%;
    left: 21%;
  }
  .zlgdh_middle_looper {
    top: 17%;
    left: 65%;
    transform: translateX(-50%);
  }
  .zlgdh_export_looper {
    top: 17%;
    right: 10%;
  }
  .zlgdh_cpc_width {
    top: 75%;
    left: 50%;
  }

  .zlgdh_inlet_looper_time {
    top: 28%;
    left: 21%;
  }
  .zlgdh_middle_looper_time {
    top: 28%;
    left: 65%;
    transform: translateX(-50%);
  }
  .zlgdh_export_looper_time {
    top: 28%;
    right: 10%;
  }

  .zlgdh_uncoiler_len_a {
    bottom: 35%;
    left: 1%;
  }
  .zlgdh_uncoiler_len_b {
    bottom: -1%;
    left: 4%;
  }
  .zlgdh_coiler_len_a {
    bottom: 45%;
    right: 1%;
  }
  .zlgdh_coiler_len_b {
    bottom: 5%;
    right: 1%;
  }
  /* END: Precise positioning examples */

  .semitransp_box.is_alarm {
    background-color: #fe2400 !important;
  }

  /* Ensure .process-stats-panel can contain absolutely positioned children */
  .process-stats-panel {
    position: relative; /* This is crucial for absolute positioning of children */
    /* You might need to adjust its height if children are positioned outside its flow */
  }

  .process-diagram {
    /* Ensure SVG background does not get a higher z-index by mistake if it also becomes positioned */
    position: relative;
    z-index: 1; /* Lower z-index than data overlays */
    /* height: 100%; */ /* Or specific height to control its area */
  }

  /* You might need to adjust existing elements like stats-overlay-container if they overlap */
  .stats-overlay-container {
    z-index: 25; /* Ensure it's above new data boxes if necessary */
  }
</style>
